﻿using System;
using System.Windows;
using System.Windows.Input;
using System.Linq;
using System.Collections.Generic;

namespace HobSoft.SoccerBet2014.Common.Wpf.Behavior
{
    public static class HotKey
    {
        private static readonly DependencyProperty HotKeysProperty =
                DependencyProperty.RegisterAttached("HotKeys", typeof(IList<KeyBinding>), typeof(HotKey), new UIPropertyMetadata(OnHotKeysChanged));

        public static readonly DependencyProperty CommandProperty =
                DependencyProperty.RegisterAttached("Command", typeof(ICommand), typeof(HotKey), new UIPropertyMetadata(OnCommandChanged));

        public static void SetCommand(FrameworkElement control, ICommand command)
        {
            if (control == null)
            {
                throw new ArgumentNullException("control");
            }
            control.SetValue(HotKey.CommandProperty, command);
        }

        public static ICommand GetCommand(FrameworkElement control)
        {
            if (control == null)
            {
                throw new ArgumentNullException("control");
            }
            return control.GetValue(HotKey.CommandProperty) as ICommand;
        }

        public static IList<KeyBinding> GetHotKeys(FrameworkElement control)
        {
            if (control == null)
            {
                throw new ArgumentNullException("control");
            }
            return control.GetValue(HotKey.HotKeysProperty) as IList<KeyBinding>;
        }

        public static void SetHotKeys(FrameworkElement control, IList<KeyBinding> keybindings)
        {
            if (control == null)
            {
                throw new ArgumentNullException("control");
            }
            control.SetValue(HotKey.HotKeysProperty, keybindings);
        }

        private static void OnHotKeysChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
        {
            var fwke = (FrameworkElement)dependencyObject;
            fwke.InputBindings.Clear();
            var tag = fwke.Tag;
            var command = GetCommand(fwke);
            var keyBindings = (e.NewValue as IList<KeyBinding>);

            if (keyBindings != null)
            {
                bool hasEnter = false;
                foreach (var keyb in keyBindings)
                {
                    if (keyb.Key == Key.Enter)
                        hasEnter = true;
                    KeyBinding newKeyb = new KeyBinding();
                    newKeyb.Key = keyb.Key;
                    newKeyb.Modifiers = keyb.Modifiers;
                    if (command != null)
                        newKeyb.Command = command;
                    newKeyb.CommandParameter = keyb.CommandParameter;
                    fwke.InputBindings.Add(newKeyb);
                }
                if (!hasEnter)
                {
                    KeyBinding confirmKeyb = new KeyBinding();
                    confirmKeyb.Key = Key.Enter;
                    if (command != null)
                        confirmKeyb.Command = command;
                    fwke.InputBindings.Add(confirmKeyb);
                }
            }
        }

        private static void OnCommandChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
        {
            var fwke = (FrameworkElement)dependencyObject;
            if (fwke.InputBindings.Count == 0) return;
            var command = e.NewValue as ICommand;
            var tag = fwke.Tag;
            foreach (var inputb in fwke.InputBindings)
            {
                var keyb = inputb as KeyBinding;
                if (keyb != null && keyb.Command == null)
                {
                    keyb.Command = command;
                }
            }
        }
    }
}
